GeometryReader

GeometryReader 是 Scripting 中与 SwiftUI 等效的几何布局读取组件。 它能够在视图构建阶段提供当前容器的尺寸、边距、安全区域和角落内边距等信息,使开发者可以根据环境动态布局内容。

当你需要根据父容器的大小进行自适应布局(响应式布局)时,GeometryReader 是非常重要的工具。


GeometryProxy

GeometryReader 构建其子内容时,会将一个 GeometryProxy 实例传递给 children 回调。开发者可以使用此对象访问与当前容器相关的布局信息。

1interface GeometryProxy {
2  readonly size: Size;
3  readonly safeAreaInsets: {
4      leading: number;
5      top: number;
6      trailing: number;
7      bottom: number;
8  };
9  /**
10   * Requires iOS 26.0+.
11   */
12  readonly containerCornerInsets: {
13      bottomLeading: Size;
14      bottomTrailing: Size;
15      topLeading: Size;
16      topTrailing: Size;
17  } | null;
18}

GeometryProxy 属性说明

1. size

1readonly size: Size

当前容器在布局时的实际尺寸。

Size 结构

1type Size = {
2  width: number
3  height: number
4}

示例

1proxy.size.width
2proxy.size.height

用于动态计算子视图布局,例如宽高比、自适应排版等。


2. safeAreaInsets

1readonly safeAreaInsets: {
2  leading: number
3  top: number
4  trailing: number
5  bottom: number
6}

当前视图所处环境中的安全区域内边距,包括顶部、底部、左右侧的避让区域。 通常用于避免内容被刘海、Home Indicator 等遮挡。

示例用途:

  • 内容距离屏幕底部安全区域以上对齐
  • 自定义导航栏、工具栏时避免被遮挡
  • 实现与设备 UI 边界一致的响应式布局

3. containerCornerInsets(iOS 26.0+)

1readonly containerCornerInsets: {
2  bottomLeading: Size
3  bottomTrailing: Size
4  topLeading: Size
5  topTrailing: Size
6} | null

该属性仅在 iOS 26+ 提供,并在设备或容器具有物理圆角偏移时报告每个角落的内边距。

用途

  • 为圆角窗口、Stage Manager 或分屏环境适配布局
  • 在容器圆角内做精确的 UI 对齐

如果平台不支持,则为 null


GeometryReader

1type GeometryReaderProps = {
2  children: (proxy: GeometryProxy) => VirtualNode;
3};
4declare const GeometryReader: FunctionComponent<GeometryReaderProps>;

Props 说明

属性名 类型 必须 说明
children (proxy: GeometryProxy) => VirtualNode 构建内容的回调函数,传入 GeometryProxy 用于读取布局信息。

工作机制

  1. GeometryReader 占据父布局中的位置,并在布局阶段获取当前容器的尺寸与安全区域信息。
  2. GeometryProxy 注入给 children(proxy) 回调。
  3. 回调返回的内容将根据读取的信息动态布局。

与 SwiftUI 一样,GeometryReader 默认会扩展到可用空间。


示例:居中布局

1import { GeometryReader, Text, VStack } from "scripting"
2
3function View() {
4  return <GeometryReader>
5    {(proxy) => {
6      return <VStack
7        frame={{
8          width: proxy.size.width,
9          height: proxy.size.height,
10          alignment: "center"
11        }}
12      >
13        <Text>Hello Geometry</Text>
14        <Text>
15          width: {proxy.size.width}
16        </Text>
17        <Text>
18          height: {proxy.size.height}
19        </Text>
20      </VStack>
21    }}
22  </GeometryReader>
23}

示例:根据安全区域调整布局

1<GeometryReader>
2  {(proxy) => {
3    return <VStack
4      padding={{
5        top: proxy.safeAreaInsets.top,
6        bottom: proxy.safeAreaInsets.bottom
7      }}
8    >
9      <Text>Content inside safe area.</Text>
10    </VStack>
11  }}
12</GeometryReader>

示例(iOS 26+):读取 containerCornerInsets

1<GeometryReader>
2  {(proxy) => {
3    const corners = proxy.containerCornerInsets
4    return <Text>
5      {corners == null
6        ? "Corner insets not available"
7        : `Top Leading Corner: ${corners.topLeading.width}, ${corners.topLeading.height}`
8      }
9    </Text>
10  }}
11</GeometryReader>

使用建议

  • 在需要响应容器尺寸时使用 GeometryReader,例如图片缩放、动态布局、等比布局。
  • 避免将大量复杂布局放入 GeometryReader 内,可能影响性能(同 SwiftUI)。